// /**
//  * 1,使用内存作为存储
//  * 2,打印sql用于验证是否正确.
//  *
//  */
//
// export enum DbAction {
//   Select = "SELECT",
//   From = "FROM"
// }
//
//
// const PrimaryKeyName: string = "id";
// const TableNameKey: string = "tableName"
// const MemDbKey: string = "memDb"
//
// export abstract class GaBaseBean {
//   static tableName: string
//   abstract id: number | undefined;
//   //获取所有属性
//   static getProperties(obj: any) {
//     // let constructor = this as new()=> object;
//     // let obj = new constructor();
//     let props = Object.getOwnPropertyNames(obj);
//     // console.log(props);
//   }
//
//   /**
//    * 实例变量获取类属性
//    */
//   getClassProp(propName: string) {
//     let proto = Object.getPrototypeOf(this)
//     let constr = proto.constructor;
//     let value = constr[propName]
//     return value;
//   }
//
//
//   /**
//    * 1 insert
//    */
//   /**
//    * 1.1 insert
//    * @returns 返回id
//    */
//   async insert<T extends DatabaseEntity>(): Promise<number> {
//     let properties: string[] = [];
//     let values: any[] = [];
//     let placeholders: string[] = []
//     let tableName = this.getClassProp(TableNameKey);
//     this.getInsertPropertiesAndValues(properties, values, placeholders);
//     console.log(properties);
//     if (!properties.length) {
//       return -1;
//     }
//     let propertiesSeg = properties.join(", ")
//     let placeholdersSeg = placeholders.join(", ")
//     let sql = `INSERT INTO ${tableName} ( ${propertiesSeg} ) VALUES ( ${placeholdersSeg} );`;
//     console.log(sql);
//
//     let tb = this.getTable();
//     tb.insert(this);
//     return this.id!;
//   }
//
//
//   getTable(): MemTable {
//     let db = this.getClassProp(MemDbKey) as MemDb;
//     let tableName = this.getClassProp(TableNameKey) as string;
//     let table = db.getTb(tableName);
//     return table;
//   }
//
//   /**
//    * 2 delete
//    */
//   /**
//    * 2.1 deleteById
//    * @returns
//    */
//   async delete<T extends DatabaseEntity>(): Promise<number> {
//     let properties: string[] = [];
//     let values: any[] = [];
//     let placeholders: string[] = []
//     // let b = proto["tableName"]
//     let proto = Object.getPrototypeOf(this)
//     let constr = proto.constructor;
//     let tableName = constr[TableNameKey]
//     this.getDeletePropertiesAndValues(properties, values, placeholders);
//     console.log(properties);
//     if (!properties.length) {
//       return -1;
//     }
//     let conditions: string[] = [];
//     for (let i = 0; i < properties.length; i++) {
//       let p = properties[i];
//       let conditionStr = `${p} = ?`
//       conditions.push(conditionStr)
//     }
//     let conditionsSeg = conditions.join(" AND ")
//     let whereSeg = conditions.length ? ` WHERE ${conditionsSeg}` : ""
//     let sql = `DELETE FROM ${tableName} ${whereSeg} ;`;
//     console.log(sql);
//     console.log(values);
//
//     let tb = this.getTable();
//     let ret = tb.delete(this);
//     return ret;
//   }
//
//   /**
//    *
//    * @param id 删除指定id的元素
//    * @returns
//    */
//   static async deleteById<T extends DatabaseEntity>(id: number): Promise<number> {
//     let properties: string[] = [PrimaryKeyName];
//     let values: any[] = [id];
//     let tableName = this.tableName;
//     let conditions: string[] = [];
//     for (let i = 0; i < properties.length; i++) {
//       let p = properties[i];
//       let conditionStr = `${p} = ?`
//       conditions.push(conditionStr)
//     }
//     let conditionsSeg = conditions.join(" AND ")
//     let whereSeg = conditions.length ? ` WHERE ${conditionsSeg}` : ""
//     let sql = `DELETE FROM ${tableName} ${whereSeg} ;`;
//     console.log(sql);
//     console.log(values);
//
//
//     let tb = this.memDb.getTb(this.tableName);
//     let ret = tb.deleteById(id);
//     return ret;
//   }
//
//
//   /**
//    * 3 update
//    */
//   /**
//    * 3 update
//    * 增量更新,
//    * ignoreUndefined 是否忽略undefined, true,undefined/null的不操作    false,undefine/null 数据库里置为null
//    * @returns
//    */
//   async updateById<T extends DatabaseEntity>(ignoreUndefined: boolean = true): Promise<number> {
//     let properties: string[] = [];
//     let values: any[] = [];
//     let placeholders: string[] = []
//     // let b = proto["tableName"]
//     let proto = Object.getPrototypeOf(this)
//     let constr = proto.constructor;
//     let tableName = constr[TableNameKey]
//     this.getInsertPropertiesAndValues(properties, values, placeholders);
//     console.log(properties);
//     if (!properties.length) {
//       return -1;
//     }
//     let updatePart = ""
//     let wherePart = ""
//     if (properties.length) {
//       let updates: string[] = [];
//       for (let i = 0; i < properties.length; i++) {
//         let p = properties[i];
//         let updateStr = `${p} = ?`
//         updates.push(updateStr)
//       }
//       let updatesStr = updates.join(" , ");
//       updatePart = `SET ${updatesStr}`
//     }
//     let idValue = this[PrimaryKeyName];
//     wherePart = `WHERE ${PrimaryKeyName} = ?`
//     values.push(idValue);
//     let sql = `UPDATE ${tableName} ${updatePart} ${wherePart} ;`;
//     console.log(sql);
//     console.log(values);
//
//     let tb = this.getTable();
//     let ret = tb.updateById(this);
//     return ret;
//   }
//
//   /**
//    * 4 search
//    */
//
//   /**
//    * 所有的数据需要返回一个拷贝
//    * 查所有的数据
//    * @returns
//    */
//   static async searchAll<T extends DatabaseEntity>(pattern?: object): Promise<T[]> {
//     _appInfo("DatabaseEntity", "searchAll", "", ActionState.Start, `pattern:${pattern ? JSON.stringify(pattern) : "no pattern"}`)
//     let sql = `${DbAction.Select} * ${DbAction.From} ${this.tableName}`;
//     console.log(`sql is: ${sql}`)
//
//     let tb = this.memDb.getTb(this.tableName);
//     let ret = tb.search(pattern) as T[];
//     return ret;
//   }
//
//
//   /**
//    *
//    * @param id 如何可以直接返回自己类型,而不用泛型?
//    * @returns
//    */
//   static async searchById<T extends DatabaseEntity>(id: number): Promise<T | null> {
//     let sql = `SELECT * FROM ${this.tableName} WHERE id = ? `;
//     console.log(`sql is: ${sql}`);
//     let tb = this.memDb.getTb(this.tableName);
//     let ret = tb.searchById(id) as T | null;
//     return ret;
//   }
//
//   /**
//    * 使用数据库查询出来的属性,进行初始化
//    * @param dbo
//    */
//   private initWithDbObject(dbo: any) {
//     let props = Object.getOwnPropertyNames(dbo);
//     if (props.length) {
//       //动态为属性赋值
//       for (let p of props) {
//         this[p] = dbo[p];
//       }
//     }
//   }
//
//   /**
//    * 外部传两个空数组,函数负责返回数据给这两个数组
//    * @param properties
//    * @param values
//    */
//   private getInsertPropertiesAndValues(properties: string[], values: any[], placeholders: string[]) {
//     let props = Object.getOwnPropertyNames(this);
//     if (props.length) {
//       //动态为属性赋值
//       for (let p of props) {
//         // console.log(`check prop : ${p}`)
//         if (p == PrimaryKeyName) {
//           continue
//         }
//         let value = this[p];
//         if (value === undefined || value === null) {
//           continue
//         }
//         properties.push(p);
//         values.push(value)
//         placeholders.push("?")
//       }
//     }
//   }
//   private getDeletePropertiesAndValues(properties: string[], values: any[], placeholders: string[]) {
//     let props = Object.getOwnPropertyNames(this);
//     if (props.length) {
//       //动态为属性赋值
//       for (let p of props) {
//         // console.log(`check prop : ${p}`)
//         if (p == PrimaryKeyName) {
//           properties.push(p);
//           let value = this[p];
//           values.push(value)
//           placeholders.push("?")
//           break;
//         }
//       }
//     }
//   }
// }
//
//
//
// /*
//   let props = Object.getOwnPropertyNames(obj);
//   可以获取实例变量的所有属性的列表.
//   */
//
